//
//  DataHelper.cpp
//  NTESAVDemo
//
//  Created by Sampson on 2024/12/30.
//

#include "DataHelper.hpp"
#include <iostream>
#include <sstream>
#include <fstream>
#include <algorithm>
// labels: __LABELS__,
using namespace std;

namespace NTES_Stats {

#if 1

const std::string chart_stats_template = R"(
    var ctx = document.getElementById('__CHART_ID__').getContext('2d');
    var chart = new Chart(ctx, {
        type: 'line',
        data: {
            labels: __LABELS__,
            datasets: __DATASETS__,
        },
        options: {
            responsive: true,
            animations: false,
            plugins: {
                legend: {
                    position: 'top'
                }
            },
        }
    });
)";

std::string BuildDataset(const std::string& label,
                               const std::vector<int>& data) {
    
    std::ostringstream dataset;
    dataset << "[{";
    dataset << "label: '" << label << "', ";
    dataset << "data: [";
    for (size_t i = 0; i < data.size(); ++i) {
        dataset << data[i];
        if (i != data.size() - 1) {
            dataset << ", ";
        }
    }
    dataset << "], ";
    dataset << "borderColor: 'rgba(75, 192, 192, 1)', ";
    dataset << "backgroundColor: 'rgba(75, 192, 192, 0.2)', ";
    dataset << "borderWidth: 2, ";
    dataset << "fill: false";
    dataset << "}]";

    return dataset.str();
}

std::string BuildMultiDatasets(std::vector<std::pair<std::string, std::vector<int>>>& datasets) {
    std::ostringstream allDatasets;
    allDatasets << "[";
    for (size_t i = 0; i < datasets.size(); ++i) {
        allDatasets << BuildDataset(datasets[i].first, datasets[i].second);
        if (i != datasets.size() - 1) {
            allDatasets << ", ";
        }
    }
    allDatasets << "]";

    return allDatasets.str();
};

std::string BuildDefaultLabels(int point_count) {
    std::ostringstream labels;
    labels << "[";
    for (int i=1; i<point_count; i++) {
        labels << i << ", ";
    }
    labels << point_count << "]";
    
    return labels.str();
    
}

// 替换模板占位符
std::string replacePlaceholder(const std::string& templateStr, const std::string& placeholder, const std::string& value) {
    std::string result = templateStr;
    size_t pos = result.find(placeholder);
    while (pos != std::string::npos) {
        result.replace(pos, placeholder.length(), value);
        pos = result.find(placeholder, pos + value.length());
    }
    return result;
}

std::string TestHTML(std::string chart_id, std::string &labels, std::string &datasets_content, std::string &html_template) {
    std::string scrip_content = chart_stats_template;
    scrip_content = replacePlaceholder(scrip_content, "__DATASETS__", datasets_content);
    scrip_content = replacePlaceholder(scrip_content, "__LABELS__", labels);
    std::string ret = html_template;
    ret = replacePlaceholder(ret, "__CHART_SCRIPT__", scrip_content);
    cout << ret << endl;
    ret = replacePlaceholder(ret, "__CHART_ID__", chart_id);
    cout << ret << endl;
    
    return ret;
}

// 生成所有图表的 JS 代码
std::string GenerateChartsScript(const std::vector<std::string>& charts_names,
                                 const std::vector<std::pair<std::string, std::vector<int>>>& charts) {
    std::ostringstream script;
    int index = 0;
    for (const auto& chart : charts) {
        std::string chart_desc = charts_names[index];
        std::string chart_js = chart_stats_template;
        chart_js = replacePlaceholder(chart_js, "__CHART_ID__", chart.first);
        chart_js = replacePlaceholder(chart_js, "__LABELS__", BuildDefaultLabels(chart.second.size()));
        chart_js = replacePlaceholder(chart_js, "__DATASETS__", BuildDataset(chart_desc, chart.second));
        script << chart_js << "\n";
        index++;
    }
    return script.str();
}

std::string BuildHTML(const std::vector<std::string>& charts_names,
                      const std::vector<std::pair<std::string, std::vector<int>>>& charts, std::string html_template) {
    std::string scripts = GenerateChartsScript(charts_names, charts);
    return replacePlaceholder(html_template, "__CHART_SCRIPT__", scripts);
}

////template <typename T>
//std::vector<int> downsample(const std::vector<int>& input, size_t max_size) {
//    size_t n = input.size();
//    if (n <= max_size) {
//        return input;  // 数据少于等于 max，直接返回
//    }
//    
//    std::vector<int> result;
//    size_t step = n / max_size;  // 计算步长
//    size_t remainder = n % max_size;  // 计算余数
//    
//    size_t index = 0;
//    for (size_t i = 0; i < max_size; ++i) {
//        size_t range_size = step + (i < remainder ? 1 : 0);  // 分配额外的点到前 remainder 组
//        auto max_it = std::max_element(input.begin() + index, input.begin() + index + range_size);
//        result.push_back(*max_it);
//        index += range_size;
//    }
//
//    return result;
//}

//template std::vector<int> downsample<int>(const std::vector<int>&);

#else


// 构建单个数据集
std::string BuildDataset(const std::string& label,
                         const std::vector<int>& data,
                         const std::string& borderColor,
                         const std::string& backgroundColor) {
    std::ostringstream dataset;
    dataset << "{"
            << "label: '" << label << "', "
            << "data: [";
    for (size_t i = 0; i < data.size(); ++i) {
        dataset << data[i];
        if (i != data.size() - 1) {
            dataset << ", ";
        }
    }
    dataset << "], "
            << "borderColor: '" << borderColor << "', "
            << "backgroundColor: '" << backgroundColor << "', "
            << "borderWidth: 2, "
            << "fill: false"
            << "}";
    return dataset.str();
}

// 构建多个数据集 (多个折线图配置)
std::string BuildMultiDatasets(const std::vector<std::pair<std::string, std::vector<int>>>& datasets,
                               const std::vector<std::pair<std::string, std::string>>& colors) {
    std::ostringstream allDatasets;
    allDatasets << "[";
    for (size_t i = 0; i < datasets.size(); ++i) {
        allDatasets << BuildDataset(datasets[i].first, datasets[i].second, colors[i].first, colors[i].second);
        if (i != datasets.size() - 1) {
            allDatasets << ", ";
        }
    }
    allDatasets << "]";
    return allDatasets.str();
}

// 生成单个图表的 JavaScript 脚本
std::string GenerateChartScript(const std::string& chartId,
                                const std::vector<std::pair<std::string, std::vector<int>>>& datasets,
                                const std::vector<std::pair<std::string, std::string>>& colors) {
    std::ostringstream script;
    script << "var ctx = document.getElementById('" << chartId << "').getContext('2d');\n";
    script << "var chart = new Chart(ctx, {\n"
           << "    type: 'line',\n"
           << "    data: {\n"
           << "        labels: [1, 2, 3, 4, 5, 6, 7],\n"
           << "        datasets: " << BuildMultiDatasets(datasets, colors) << "\n"
           << "    },\n"
           << "    options: {\n"
           << "        responsive: true,\n"
           << "        plugins: {\n"
           << "            legend: {\n"
           << "                position: 'top'\n"
           << "            }\n"
           << "        },\n"
           << "        scales: {\n"
           << "            x: {\n"
           << "                title: {\n"
           << "                    display: true,\n"
           << "                    text: 'X Axis'\n"
           << "                }\n"
           << "            },\n"
           << "            y: {\n"
           << "                title: {\n"
           << "                    display: true,\n"
           << "                    text: 'Y Axis'\n"
           << "                }\n"
           << "            }\n"
           << "        }\n"
           << "    }\n"
           << "});\n";
    return script.str();
}

// 生成多个图表的 HTML 和 JavaScript
std::string GenerateMultipleChartsHTML(const std::vector<std::string>& chartIds,
                                       const std::vector<std::vector<std::pair<std::string, std::vector<int>>>>& allDatasets,
                                       const std::vector<std::vector<std::pair<std::string, std::string>>>& allColors) {
    std::ostringstream html;
    html << "<!DOCTYPE html>\n"
         << "<html lang='en'>\n"
         << "<head>\n"
         << "    <meta charset='UTF-8'>\n"
         << "    <meta name='viewport' content='width=device-width, initial-scale=1.0'>\n"
         << "    <title>Dynamic Charts</title>\n"
         << "    <script src='chart.umd.js'></script>\n"
         << "    <style>\n"
         << "        canvas {\n"
         << "            width: 80%;\n"
         << "            height: 400px;\n"
         << "            margin: 20px auto;\n"
         << "            display: block;\n"
         << "        }\n"
         << "    </style>\n"
         << "</head>\n"
         << "<body>\n";

    // 渲染多个 canvas
    for (const auto& id : chartIds) {
        html << "    <h3>Chart: " << id << "</h3>\n";
        html << "    <canvas id='" << id << "'></canvas>\n";
    }

    html << "    <script>\n";

    // 渲染多个图表脚本
    for (size_t i = 0; i < chartIds.size(); ++i) {
        html << GenerateChartScript(chartIds[i], allDatasets[i], allColors[i]);
    }

    html << "    </script>\n"
         << "</body>\n"
         << "</html>";
    return html.str();
}


int TestWriteToFile(std::string &filePath) {
    std::vector<std::string> chartIds = {"chart1", "chart2", "chart3"};

    // 数据集
    std::vector<std::vector<std::pair<std::string, std::vector<int>>>> allDatasets = {
        {{"CPU 使用率", {10, 20, 30, 40, 50}}, {"内存使用率", {5, 15, 25, 35, 45}}},
        {{"磁盘使用率", {8, 18, 28, 38, 48}}, {"网络延迟", {3, 13, 23, 33, 43}}},
        {{"GPU 使用率", {12, 22, 32, 42, 52}}, {"电源使用率", {7, 17, 27, 37, 47}}}
    };

    // 颜色配置
    std::vector<std::vector<std::pair<std::string, std::string>>> allColors = {
        {{"rgba(255,99,132,1)", "rgba(255,99,132,0.2)"}, {"rgba(54,162,235,1)", "rgba(54,162,235,0.2)"}},
        {{"rgba(255,159,64,1)", "rgba(255,159,64,0.2)"}, {"rgba(153,102,255,1)", "rgba(153,102,255,0.2)"}},
        {{"rgba(75,192,192,1)", "rgba(75,192,192,0.2)"}, {"rgba(201,203,207,1)", "rgba(201,203,207,0.2)"}}
    };

    std::string htmlContent = GenerateMultipleChartsHTML(chartIds, allDatasets, allColors);

    // 保存到文件
    std::ofstream htmlFile(filePath);
    htmlFile << htmlContent;
    htmlFile.close();

    std::cout << "Charts have been generated in charts.html" << std::endl;

    return 0;
}


#endif

};
